using ColorFillGame.Domain.Exceptions;
using ColorFillGame.Domain.ValueObjects;

namespace ColorFillGame.Domain.Entities;

public class GameGrid
{
    private readonly Dictionary<Position, PlayerColor> _cells;
    public int Size { get; private set; }

    public GameGrid(int size)
    {
        if (size <= 0)
            throw new DomainException("Grid size must be positive.");
        
        Size = size;
        _cells = new Dictionary<Position, PlayerColor>();
        
        // Initialize the grid with some random colors
        InitializeGrid();
    }

    private void InitializeGrid()
    {
        // 初始化為空白網格，不預先填充任何顏色
        // 這樣玩家可以從空白狀態開始塗色
        // 網格將在遊戲進行中逐漸被玩家填充
    }

    public void FillPosition(Position position, PlayerColor color)
    {
        if (!position.IsValid(Size))
            throw new DomainException("Invalid position.");
        
        // 直接填充指定位置，支持覆蓋已塗色的格子
        // 這樣玩家可以重新塗色任何位置
        _cells[position] = color;
    }

    public PlayerColor? GetCellColor(Position position)
    {
        if (!position.IsValid(Size))
            throw new DomainException("Invalid position.");
        
        if (_cells.TryGetValue(position, out var color))
            return color;
        
        return null;
    }

    public List<Position> GetFilledCellsByColor(PlayerColor color)
    {
        return _cells.Where(kvp => kvp.Value == color).Select(kvp => kvp.Key).ToList();
    }

    public Dictionary<PlayerColor, int> GetColorDistribution()
    {
        var distribution = new Dictionary<PlayerColor, int>();
        
        foreach (var color in _cells.Values)
        {
            if (distribution.ContainsKey(color))
                distribution[color]++;
            else
                distribution[color] = 1;
        }
        
        return distribution;
    }

    public int GetTotalFilledCells()
    {
        return _cells.Count;
    }

    public int GetTotalEmptyCells()
    {
        return Size * Size - _cells.Count;
    }
}